using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Xeml.Document;
using Mpi.Common.Collections;
using Xid.Controls.ParameterBrowserCtrls;
using Xeml.Document.Contracts;

namespace Xid.Controls.ParameterEditCtrls
{
    public partial class ParameterEditCtrl : UserControl
    {

        #region Fields
        private List<ContextEditCtrl> contextCtrlPool = new List<ContextEditCtrl>();
        private StoryBase _story;

        #endregion

        public ParameterEditCtrl()
        {
            InitializeComponent();
            kryptonPanelContextCtrls.Controls.Clear();
            IncCtrlPool(3);
            //this.parameterTreeCtrl.SelectedParamTreeNodeChanged += new EventHandler(OnParamTreeNodeSelected);
            //this.parameterTreeCtrl.ParameterPopulated += new EventHandler(OnParameterTreeParameterPopulated);
            //this.parameterTreeCtrl.ParameterDePopulated += new EventHandler(OnParameterTreeParameterDePopulated);
            this.timePointStackCtrl1.PointSelected += new EventHandler<Mpi.Common.PropertyHasChangedEventArgs<TimeSpan>>(OnTimePointStackCtrl_PointSelected);
            this.timePointStackCtrl1.PointChanged += new EventHandler<Mpi.Common.PropertyHasChangedEventArgs<TimeSpan>>(OnTimePointStackCtrl_PointChanged);
            this.timePointStackCtrl1.PointDroped += new EventHandler<Mpi.Common.PropertyHasChangedEventArgs<TimeSpan>>(OnTimePointStackCtrl_PointDroped);
        }

        #region Methods

        /// <summary>
        /// Increases the pool of context edit controls.
        /// </summary>
        /// <param name="poolSize">The total number of controls.</param>
        private void IncCtrlPool(int poolSize)
        {
            if (this.contextCtrlPool.Count < poolSize)
            {
                kryptonPanelContextCtrls.SuspendLayout();

                for (int i = this.contextCtrlPool.Count; i < poolSize; i++)
                {

                    ContextEditCtrl cec = new ContextEditCtrl();
                    cec.Name = "CEC_" + i;
                    kryptonPanelContextCtrls.Controls.Add(cec);
                    cec.MinimumSize = new Size(250, 0);
                    cec.MaximumSize = new Size(250, 0);
                    cec.Margin = new Padding(0, 0, 0, 20);
                    if (contextCtrlPool.Count > 0)
                        cec.Location = new Point(contextCtrlPool[contextCtrlPool.Count - 1].Right + 2, 5);
                    else
                        cec.Location = new Point(2, 5);
                    cec.SetupSpec(null, null, null, Color.White);
                    cec.ParameterPopulated += new EventHandler(OnContextEdtCtrlParameterPopulated);
                    cec.ParameterDePopulated += new EventHandler(OnContextEdtCtrlParameterDePopulated);
                    contextCtrlPool.Add(cec);
                }
                kryptonPanelContextCtrls.ResumeLayout();
            }
        }

        /// <summary>
        /// Initializes this control.
        /// </summary>
        /// <param name="handler">The environmental ontology handler</param>
        /// <param name="observationTime">The observation time of the whole experiment.</param>
        public void Setup( TimeSpan observationTime)
        {
            this.timePointStackCtrl1.MaxTime = observationTime;
           // this.parameterTreeCtrl.Setup(handler,filterLevel);
        }


        /// <summary>
        /// Loads the content of a story.
        /// </summary>
        /// <param name="sb">The story to load.</param>
        //public void NavigateTo(StoryBase sb)
        //{
        //    this._story = sb;
        //    if (sb is Story)
        //        timePointStackCtrl1.MinTime = TimeSpan.Zero;
        //    else if (sb is StorySplit)
        //        timePointStackCtrl1.MinTime = (sb as StorySplit).TimePoint;
        //    //this.parameterTreeCtrl.SetupStory(sb, filterLevel);
        //    //this.parameterTreeCtrl.SelectFirst();
        //}

        private string _currentParameterId;
        private IDynamicOntologyTerm _currentSupervisor;

        /// <summary>
        /// Loads the content of a story and navigates to a specific parameter.
        /// </summary>
        /// <param name="sb">The story to load.</param>
        /// <param name="termId">The id of teh parametetr to navigate.</param>
        public void NavigateTo(StoryBase sb, IDynamicOntologyTerm supvis, string termId)
        {
            _currentParameterId = termId;
            _currentSupervisor = supvis;
            if (_story != sb)
            {
                if (_story != null)
                {
                    _story.Variables.ItemAdded -= new EventHandler<ItemEventArgs<Term>>(Parameters_ItemAdded);
                    _story.Variables.ItemRemoved -= new EventHandler<ItemEventArgs<Term>>(Parameters_ItemRemoved);
                    _story.Variables.Cleared -= new EventHandler(Parameters_Cleared);
                }
                _story = sb;
                _story.Variables.ItemAdded += new EventHandler<ItemEventArgs<Term>>(Parameters_ItemAdded);
                _story.Variables.ItemRemoved += new EventHandler<ItemEventArgs<Term>>(Parameters_ItemRemoved);
                _story.Variables.Cleared += new EventHandler(Parameters_Cleared);
                if (sb is Story)
                    timePointStackCtrl1.MinTime = TimeSpan.Zero;
                else if (sb is StorySplit)
                    timePointStackCtrl1.MinTime = (sb as StorySplit).TimePoint;
            }
            //this.parameterTreeCtrl.SetupStory(sb,filterLevel);
            //this.parameterTreeCtrl.SelectById(termId);
            NavigateTo(sb.Variables.Find(termId), supvis);
        }

        void Parameters_Cleared(object sender, EventArgs e)
        {
            NavigateTo(null, _currentSupervisor);
        }

        void Parameters_ItemRemoved(object sender, ItemEventArgs<Term> e)
        {
            if (e.Item.TermId == _currentParameterId)
                NavigateTo(null, _currentSupervisor);
        }

        void Parameters_ItemAdded(object sender, ItemEventArgs<Term> e)
        {
            if (e.Item.TermId == _currentParameterId)
                NavigateTo(e.Item, _currentSupervisor);
        }

        public void NavigateTo(Term p, IDynamicOntologyTerm supvis)
        {

            DynamicTerm dt = p as DynamicTerm;
            //foreach (ContextEditCtrl cec in this.contextCtrlPool)
            //{
            //    cec.SetupSpec(null, null, null, Color.White);
            //}
            IncCtrlPool(supvis.ContextCount);
            for (int i = 0; i < contextCtrlPool.Count; i++)
            {
                contextCtrlPool[i].Visible = i < supvis.ContextCount;
                contextCtrlPool[i].Enabled = contextCtrlPool[i].Visible;
            }

            // TimeSpan[] t = pcc.Parameter.Values.ListDistinctIdentifiers();

            

            string[] contexts = supvis.Contexts;
            for (int i = 0; i < contexts.Length; i++)
            {
                contextCtrlPool[i].SetupSpec(supvis, contexts[i], supvis.Prototype.NameSpaceAlias, ContextColorMgr.Instance.Map(contexts[i]));
                if (p != null)
                {
                    contextCtrlPool[i].Parameter = dt;
                    if(dt.Values.Count > 0)
                        contextCtrlPool[i].NavigateTo(dt.Values[0].Time);
                    else
                        contextCtrlPool[i].NavigateTo(TimeSpan.Zero);
                }
                else
                {
                    contextCtrlPool[i].Parameter = null;
                    contextCtrlPool[i].NavigateTo(TimeSpan.Zero);
                }
            }
            this.kryptonHeaderValueTimeNav.Values.Description = supvis.TermId + ":" + supvis.Prototype.Name;
            
            
            this.timePointStackCtrl1.Populate(_story, dt);

            //if (p != null && p.Values.Count > 0)
            //{
                
            //        this.timePointStackCtrl1.Populate(p);
                
            //}
            //else
            //{

            //    if (_story is Story || _story == null)
            //        this.timePointStackCtrl1.Populate(p,TimeSpan.Zero );
            //    if (_story is StorySplit)
            //        this.timePointStackCtrl1.Populate(p, (_story as StorySplit).TimePoint);
            //}

        }

        #endregion


        #region Eventhandler
        void OnTimePointStackCtrl_PointDroped(object sender, Mpi.Common.PropertyHasChangedEventArgs<TimeSpan> e)
        {
            foreach (ContextEditCtrl cec in this.contextCtrlPool)
            {
                cec.DropValue();
            }
        }

        void OnTimePointStackCtrl_PointChanged(object sender, Mpi.Common.PropertyHasChangedEventArgs<TimeSpan> e)
        {
            foreach (ContextEditCtrl cec in this.contextCtrlPool)
            {
                cec.TargetTime = e.NewValue;
            }
        }

        void OnTimePointStackCtrl_PointSelected(object sender, Mpi.Common.PropertyHasChangedEventArgs<TimeSpan> e)
        {
            foreach (ContextEditCtrl cec in this.contextCtrlPool)
            {
                if (cec.Visible)
                    cec.NavigateTo(e.NewValue);
                
            }
        }


        void OnContextEdtCtrlParameterDePopulated(object sender, EventArgs e)
        {
            ContextEditCtrl cec = sender as ContextEditCtrl;
            DynamicTerm toRemove = cec.Parameter;
            //this.parameterTreeCtrl.SelectedNode.Parameter.Collection = null;
            //this.parameterBrowserCtrl1.SelectedCtrl.Parameter = null;
            //foreach (ContextEditCtrl x in this.contextCtrlPool)
            //{
            //    x.Parameter = null;
            //}
            _story.Variables.Remove(toRemove);

        }

        void OnContextEdtCtrlParameterPopulated(object sender, EventArgs e)
        {
            ContextEditCtrl cec = sender as ContextEditCtrl;
            //foreach (ContextEditCtrl x in this.contextCtrlPool)
            //{
            //    x.Parameter = cec.Parameter;
            //}
            _story.Variables.Add(cec.Parameter);

            //this.parameterTreeCtrl.Story.Parameters.Add(cec.Parameter);

            //this.parameterBrowserCtrl1.SelectedCtrl.Parameter = cec.Parameter;
        }


        //void OnParameterTreeParameterDePopulated(object sender, EventArgs e)
        //{
        //    foreach (ContextEditCtrl cec in this.contextCtrlPool)
        //    {
        //        cec.Parameter = null;
        //        cec.NavigateTo(TimeSpan.Zero);
        //    }
        //}


        //void OnParameterTreeParameterPopulated(object sender, EventArgs e)
        //{
        //    //if (sender == this.parameterTreeCtrl.SelectedNode)
        //    //{
        //    //ParameterComposerCtrl pcc = (ParameterComposerCtrl)sender;
        //    for (int i = 0; i < this.parameterTreeCtrl.SelectedNode.ParameterSupervisor.ContextCount; i++)
        //    {
        //        if (this.parameterTreeCtrl.SelectedNode.Parameter != null)
        //        {
        //            contextCtrlPool[i].Parameter = this.parameterTreeCtrl.SelectedNode.Parameter;
        //            contextCtrlPool[i].NavigateTo(this.parameterTreeCtrl.SelectedNode.Parameter.Values[0].Time);
        //        }
        //        else
        //        {
        //            contextCtrlPool[i].Parameter = null;
        //            contextCtrlPool[i].NavigateTo(TimeSpan.Zero);
        //        }
        //    }
        //    // }
        //}




        //private void SetInfoPanel(ParamTreeNode ptn)
        //{
        //    this.kryptonLabelNameVal.Text = ptn.ParameterSupervisor.Name;
        //    this.kryptonLabelNsAliasVal.Text = ptn.ParameterSupervisor.NameSpaceAlias;
        //    this.kryptonLabelGroupVal.Text = ptn.ParameterSupervisor.GroupPath;
        //    this.textBoxDescription.Text = ptn.ParameterSupervisor.Description;
        //} 
        #endregion

       
    }
}
